#pragma once
#include "gtest/gtest.h"
#include "DataStructure/Common/Real.h"
#include "DBManager/DBServiceFactory.h"
// #include "SGFem/Pre/Assembly/Assembly.h"
// #include "Utility/Algebra/MathTools.h"
// #include "SGFem/Pre/Assembly/CoordinateProcessor.h"
// #include "../../Factory/ElementCalculatorFactory.h"
#include "../CweldCalculator.h"

#include "DataStructure/Input/Property/PBARData.h"
#include "DataStructure/Input/Property/PWELDData.h"

using SG::Algebra::Matrixd;
using SG::Algebra::Vector3D;
using SG::Algebra::Point;
using SG::DataStructure::Common::Real;
using SG::DataStructure::Common::TOLERANCE;
using namespace SG::DataStructure::FEM;
using namespace SG::DBManager;
// using SG::FEMSolver::AssemblyEigen;
// using SG::FEMSolver::CoordinateProcessor;
// using SG::FEMSolver::Element::ElementCalculatorFactory;
using SG::FEMSolver::Element::CweldCalculator;

//长度为零的特殊情况
TEST (CweldCalculatorTest, ComputeStiffness0)
{
    // Input data
    Real tA = 0.01;
    Real tB = 0.01;
    Real Le = (tA + tB) / 2.0;

    PBARData           pBar;
    IsotropicMaterial  material;
    // pBar.SetGroup ("MSCBML0");
    pBar.m_A   = 0.0078539816339744835;
    pBar.m_I1  = 4.9087385212340534e-06;
    pBar.m_J   = 9.8174770424681068e-06;

    material.m_E = 200000000000;
    material.m_G = 76923077000;

    // Test data 
    Matrixd klTest(12, 12);
    CweldCalculator calculator;
    calculator.ComputeStiffness0(Le, material, pBar, _OUT klTest);
                                                                  
    Matrixd T(3,3,{0,0,-1,0,-1,0,1,0,0});
    Matrixd TBeam (12, 12);
    TBeam.BlockFill (0, 0, T);
    TBeam.BlockFill (3, 3, T);
    TBeam.BlockFill (6, 6, T);
    TBeam.BlockFill (9, 9, T);
    klTest = TBeam.Transpose () * klTest * TBeam;   
                          
    // Target data
    const Matrixd klTarget (12, 12 ,{
        60415243398.680496,	  0,	                0,	                  0,	                 0,	                    0,	               -60415243398.680496,	    0,	                    0,	                      0,	                 0,	                    0,
         0,	                  60415243398.680496,	0,	                  0,	                 0,	                    0,	                0,	                   -60415243398.680496,	    0,	                      0,	                 0,	                    0,
         0,	                  0,	                157079632679.48965,	  0,	                 0,	                    0,	                0,	                    0,	                   -157079632679.48965,	      0,	                 0,	                    0,
         0,	                  0,	                0,	                  98174770.424681067,	 0,	                    0,	                0,	                    0,	                    0,	                     -98174770.424681067,	 0,	                    0,
         0,	                  0,	                0,	                  0,	                 98174770.424681067,	0,	                0,	                    0,	                    0,	                      0,	                -98174770.424681067,	0,
         0,	                  0,	                0,	                  0,	                 0,	                    75519054.24835065,	0,	                    0,	                    0,	                      0,	                 0,	                   -75519054.24835065,
        -60415243398.680496,  0,	                0,	                  0,	                 0,	                    0,	                60415243398.680496,	    0,	                    0,	                      0,	                 0,	                    0,
         0,	                 -60415243398.680496,	0,	                  0,	                 0,	                    0,	                0,	                    60415243398.680496,	    0,	                      0,	                 0,	                    0,
         0,	                  0,	               -157079632679.48965,   0,	                 0,	                    0,	                0,	                    0,	                    157079632679.48965,	      0,	                 0,	                    0,
         0,	                  0,	                0,	                 -98174770.424681067,	 0,	                    0,	                0,	                    0,	                    0,	                      98174770.424681067,	 0,	                    0,
         0,	                  0,	                0,	                  0,	                -98174770.424681067,	0,	                0,	                    0,	                    0,	                      0,	                 98174770.424681067,	0,
         0,	                  0,	                0,	                  0,	                 0,	                   -75519054.24835065,	0,	                    0,	                    0,	                      0,	                 0,	                    75519054.24835065

    });
    // Check
    ASSERT_TRUE (klTarget == klTest);
};

TEST (CweldCalculatorTest, Q4T3ComputeProjectionPoint)
{
    // 判断 “斜三角形-斜四边形” 投影是否正确
    // Input data
    Point gS{7.5, 7.5, 3.0};
    Point GA;
    SG::Algebra::PointArray gASet;
    gASet = SG::Algebra::PointArray(4);
    gASet[0] = Point{7.5, 12.5, 0.0};
    gASet[1] = Point{6.25, 4.99999952316284 ,0.0};
    gASet[2] = Point{12.5, 4.99999952316284 ,0.0};
    gASet[3] = Point{15.0, 15.0, 0.0};

    Point GB;
    SG::Algebra::PointArray gBSet;
    gBSet = SG::Algebra::PointArray(3);
    gBSet[0] = Point{5.0, 5.0, 5.0};
    gBSet[1] = Point{13.0, 7.0, 6.0};
    gBSet[2] = Point{7.0, 13.0, 6.0};
    Vector3D nA;
    // Test data
    SG::FEMSolver::Element::CweldCalculator calculator;
    calculator.ComputeProjectionPoint2 (gS,gASet,gBSet,_OUT GA,_OUT GB,_OUT nA);

    // Check
    ASSERT_NEAR (GA.m_x, 7.49999952316284, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_y, 7.5, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_z, 0.0, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_x, 7.25490188598633, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_y, 7.25490188598633, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_z, 5.4509801864624, SG::DataStructure::Common::TOLERANCE);
}

//四节点约束方程验算(水平)
TEST (CweldCalculatorTest, ComputeConstrantEquation)
{
    // Input data
    Point Gi{7.5, 5.0, 0.0};
    SG::Algebra::PointArray Giset(4);
    Giset[0] = { 0, 10, 0};
    Giset[1] = { 0,  0, 0};
    Giset[2] = {10, -5, 0};
    Giset[3] = {15,  5, 0};

    SG::DataStructure::Common::IdArray dispCoord = {0, 0, 0, 0};
    // Test data 
    SG::Algebra::Matrixd    RTest;

    SG::DataStructure::Common::Id dispId = 0;
    CweldCalculator::ComputeConstrantEquation (Gi ,dispId, Giset, dispCoord, _OUT RTest);
    // Target data
    const Matrixd RTarget (6, 12 ,{
        0.35345316287277462,	-1.38777878078144E-17,	0,	                     0.10516557197811556,	-6.93889390390722E-18,	0,	                    0.12414379544732951,	-6.93889390390722E-18,	0,	                        0.41723746970178027,   -2.77555756156289E-17,	0,	                 
       -2.77555756156289E-17,	 0.35345316287277467,	0,	                    -6.93889390390722E-18,	 0.10516557197811553,	0,	                   -6.93889390390722E-18,	 0.12414379544732948,	0,	                       -2.77555756156289E-17,	0.41723746970178022,	0,	                 
        0,	                     0,	                    0.35345316287277467,	 0,	                     0,	                    0.10516557197811555,	0,	                     0,	                    0.12414379544732951,	    0,	                    0,	                    0.41723746970178027,
        0,	                     0,	                    0.055498734131696606,	 0,	                     0,	                   -0.0376982277843752,	    0,	                     0,	                   -0.053401519041964,	        0,	                    0,	                    0.03560101269464272,
        0,	                     0,	                    0.035601012694642706,	 0,	                     0,	                    0.030158582227500206,	0,	                     0,	                    0.0027212152335712534,	    0,	                    0,	                   -0.0684808101557141,	 
       -0.0277493670658483,	    -0.0178005063473213,	0,	                     0.01884911389218763,	-0.0150792911137501,	0,	                    0.026700759520982029,	-0.00136060761678562,	0,	                       -0.0178005063473213,	    0.034240405077857083,	0	                 

    });
    // Check
    ASSERT_TRUE (RTarget == RTest);
}

TEST (CweldCalculatorTest, ComputeConstrantEquation_T3)
{
    Point Gi{7.2772277227722775, 5, 5.2277227722772288};
    SG::Algebra::PointArray Giset(3);
    Giset[0] = { 5,  0, 5};
    Giset[1] = { 15, 5, 6};
    Giset[2] = { 5, 10, 5};

    // Test data 
    SG::Algebra::Matrixd    RTest;
    
    SG::DataStructure::Common::Id dispId = 0;
    SG::DataStructure::Common::IdArray dispCoord = {0, 0, 0, 0};
    CweldCalculator::ComputeConstrantEquation (Gi, dispId, Giset, dispCoord, _OUT RTest);
    // Target data
    const Matrixd RTarget (6, 9 ,{
         0.38613861386138615,	-5.55111512312578E-17,	-6.93889390390722E-18,	 0.22772277227722773,	-1.38777878078144E-17, -3.46944695195361E-18,	 0.38613861386138609,	   -2.77555756156289E-17,	-6.93889390390722E-18,
        -5.55111512312578E-17,	 0.38613861386138626,	-1.7347234759768E-18,	-1.38777878078144E-17,	 0.22772277227722773,	0,	                    -2.77555756156289E-17,	    0.38613861386138615,	-1.7347234759768E-18,
        -6.93889390390722E-18,	-1.7347234759768E-18,	 0.38613861386138632,	-6.93889390390722E-18,	-1.7347234759768E-18,	0.22772277227722781,	 0,	                        1.7347234759768071e-18,	 0.3861386138613862,
         0.0049504950495049506,	 0.0024752475247524748,	-0.0995049504950495,	-5.1352976067341E-19,	-0.00495049504950494,	1.3836020040930281e-17, -0.00495049504950494,	    0.0024752475247524753,	 0.09950495049504951,
        -0.00495049504950495,	 0,	                     0.049504950495049514,	 0.0099009900990099011,	 0,	                   -0.099009900990099,	    -0.00495049504950494,	    0,	                     0.049504950495049507,
         0.050495049504950498,	-0.0247524752475247,	-0.00495049504950495,	-3.55575267061997E-18,	 0.049504950495049507,	8.6305718666363397e-19,	-0.0504950495049504,	   -0.0247524752475247,	     0.0049504950495049497
    });

    // Check
    ASSERT_TRUE(RTest  == RTarget);
}

TEST (CweldCalculatorTest, Q4T3_out_ComputeProjectionPoint)
{
    // 判断 “3节点斜三角形-4节点斜四边形-GS点位于平面外（二次投影）” 投影是否正确
    // Input data
    Point gS{7.5, 7.5, -3.0};
    Point GA;
    SG::Algebra::PointArray gASet;
    gASet = SG::Algebra::PointArray(4);
    gASet[0] = Point{7.5, 12.5, 0.0};
    gASet[1] = Point{6.25, 4.99999952316284 ,0.0};
    gASet[2] = Point{12.5, 4.99999952316284 ,0.0};
    gASet[3] = Point{15.0, 15.0, 0.0};

    Point GB;
    SG::Algebra::PointArray gBSet;
    gBSet = SG::Algebra::PointArray(3);
    gBSet[0] = Point{5.0, 5.0, 5.0};
    gBSet[1] = Point{13.0, 7.0, 6.0};
    gBSet[2] = Point{7.0, 13.0, 6.0};
    Vector3D nA;
    // Test data
    SG::FEMSolver::Element::CweldCalculator calculator;
    calculator.ComputeProjectionPoint2 (gS,gASet,gBSet,_OUT GA,_OUT GB,_OUT nA);

    // Check
    // 误差小 注释掉的为nastran算出来的结果
    // ASSERT_NEAR (GA.m_x, 7.08333253860474, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GA.m_y, 7.08334922790527, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GA.m_z, 0.0, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GB.m_x, 6.81372499465942, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GB.m_y, 6.81372690200806, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GB.m_z, 5.36274528503418, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_x, 7.083333333333333, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_y, 7.083333333333333, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_z, 0.0, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_x, 6.8137254901960782, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_y, 6.8137254901960782, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_z, 5.3627450980392162, SG::DataStructure::Common::TOLERANCE);
}

TEST (CweldCalculatorTest, T3T3_under_ComputeProjectionPoint)
{
    // 判断ELEMID投影是否正确
    // CASE: 3节点斜三角形-3节点斜四边形-GS点位于平面外（位于两板下方的二次投影）
    // Input data
    Point gS{13, 4, 0};
    Point GA;
    SG::Algebra::PointArray gASet;
    gASet = SG::Algebra::PointArray(3);
    gASet[0] = Point{20.0, 0.0, 2.0};
    gASet[1] = Point{10.0, 10.0 ,2.0};
    gASet[2] = Point{0.0, 0.0 ,0.0};

    Point GB;
    SG::Algebra::PointArray gBSet;
    gBSet = SG::Algebra::PointArray(3);
    gBSet[0] = Point{18.0, 5.0, 7.0};
    gBSet[1] = Point{11.0, 10.0, 6.5};
    gBSet[2] = Point{10.0, 0.0, 6.0};
    Vector3D nA;

    // Test data
    SG::FEMSolver::Element::CweldCalculator calculator;
    calculator.ComputeProjectionPoint2 (gS,gASet,gBSet,_OUT GA,_OUT GB,_OUT nA);

    // Check
    ASSERT_NEAR (GA.m_x, 12.8314552307129, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_y, 4.02303266525269, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_z, 1.68544888496399, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_x, 12.3616056442261, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_y, 3.69464206695557, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_z, 6.38394641876221, SG::DataStructure::Common::TOLERANCE);
}

TEST (CweldCalculatorTest, T3T3_under_ComputeProjectionPoint_verse)
{
    // 判断ELEMID投影是否正确
    // CASE: 3节点斜三角形-3节点斜四边形-GS点位于平面外（位于两板下方的二次投影）
    // 特别说明：由于翻转了gASet的顺序，法向量朝向会反过来，但是函数依然能处理此类情况的投影求解。
    // Input data
    Point gS{13, 4, 0};
    Point GA;
    SG::Algebra::PointArray gASet;
    gASet = SG::Algebra::PointArray(3);
    gASet[2] = Point{20.0, 0.0, 2.0};
    gASet[1] = Point{10.0, 10.0 ,2.0};
    gASet[0] = Point{0.0, 0.0 ,0.0};

    Point GB;
    SG::Algebra::PointArray gBSet;
    gBSet = SG::Algebra::PointArray(3);
    gBSet[0] = Point{18.0, 5.0, 7.0};
    gBSet[1] = Point{11.0, 10.0, 6.5};
    gBSet[2] = Point{10.0, 0.0, 6.0};
    Vector3D nA;

    // Test data
    SG::FEMSolver::Element::CweldCalculator calculator;
    calculator.ComputeProjectionPoint2 (gS,gASet,gBSet,_OUT GA,_OUT GB,_OUT nA);

    // Check
    ASSERT_NEAR (GA.m_x, 12.8314552307129, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_y, 4.02303266525269, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_z, 1.68544888496399, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_x, 12.3616056442261, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_y, 3.69464206695557, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_z, 6.38394641876221, SG::DataStructure::Common::TOLERANCE);
}

TEST (CweldCalculatorTest, T3T3_mid_ComputeProjectionPoint)
{
    // 判断ELEMID投影是否正确
    // CASE: 3节点斜三角形-3节点斜四边形-GS点位于两单元间（一次投影）
    // Input data
    Point gS{13, 4, 3};
    Point GA;
    SG::Algebra::PointArray gASet;
    gASet = SG::Algebra::PointArray(3);
    gASet[0] = Point{20.0, 0.0, 2.0};
    gASet[1] = Point{10.0, 10.0 ,2.0};
    gASet[2] = Point{0.0, 0.0 ,0.0};

    Point GB;
    SG::Algebra::PointArray gBSet;
    gBSet = SG::Algebra::PointArray(3);
    gBSet[0] = Point{18.0, 5.0, 7.0};
    gBSet[1] = Point{11.0, 10.0, 6.5};
    gBSet[2] = Point{10.0, 0.0, 6.0};
    Vector3D nA;
    // Test data
    SG::FEMSolver::Element::CweldCalculator calculator;
    calculator.ComputeProjectionPoint2 (gS,gASet,gBSet,_OUT GA,_OUT GB,_OUT nA);

    // Check
    ASSERT_NEAR (GA.m_x, 13.1274509429932, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_y, 4.12745094299316, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_z, 1.72549021244049, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_x, 12.6579675674438, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_y, 3.86318707466125, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_z, 6.42032432556152, SG::DataStructure::Common::TOLERANCE);
}

TEST (CweldCalculatorTest, T6Q8_up_ComputeProjectionPoint)
{
    // 判断GRIDID投影是否正确
    // CASE: 6节点斜三角形-8节点斜四边形-GS点位于平面外（位于两板上方的二次投影）

    // Input data
    Point gS{4, 4, 6};
    Point GA;
    SG::Algebra::PointArray gASet;
    gASet = SG::Algebra::PointArray(6);
    gASet[0] = Point{0.0, 0.0, 0.0};
    gASet[1] = Point{10.5, 0.0 ,1.0};
    gASet[2] = Point{0.5, 10.0 ,0.5};
    gASet[3] = Point{5.24999952316284, 0.0, 0.499999970197678};
    gASet[4] = Point{5.49999952316284, 4.99999952316284 ,0.749999940395355};
    gASet[5] = Point{0.25, 5.0 ,0.25};

    Point GB;
    SG::Algebra::PointArray gBSet;
    gBSet = SG::Algebra::PointArray(8);
    gBSet[0] = Point{2.0, 0.0, 5};
    gBSet[1] = Point{5.5, 0.0, 5.25};
    gBSet[2] = Point{6.0, 5.0, 5.5};
    gBSet[3] = Point{2.5, 6.0, 5.25};
    gBSet[4] = Point{3.75, 0.0, 5.125};
    gBSet[5] = Point{5.75, 2.49999976158142, 5.375};
    gBSet[6] = Point{4.25, 5.0, 5.375};
    gBSet[7] = Point{2.25, 2.49999976158142, 5.125};
    Vector3D nA;
    // Test data
    SG::FEMSolver::Element::CweldCalculator calculator;
    calculator.ComputeProjectionPoint2 (gS,gASet,gBSet,_OUT GA,_OUT GB,_OUT nA);

    // Check
    // ASSERT_NEAR (GA.m_x, 4.50418901443481, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GA.m_y, 4.24252986907959, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GA.m_z, 0.620894312858582, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GB.m_x, 4.11232566833496, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GB.m_y, 4.03538227081299, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GB.m_z, 5.32382535934448, SG::DataStructure::Common::TOLERANCE);
    // 注释掉的为Nastran计算结果，投影点坐标最大误差0.3%。
    ASSERT_NEAR (GA.m_x, 4.505906225, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_y, 4.240975427, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_z, 0.620987576, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_x, 4.102506725, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_y, 4.044850617, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_z, 5.307687079, SG::DataStructure::Common::TOLERANCE);
}

TEST (CweldCalculatorTest, T6Q8_up_ComputeProjectionPoint_verse)
{
    // 判断GRIDID投影是否正确
    // CASE: 6节点斜三角形-8节点斜四边形-GS点位于平面外（位于两板上方的二次投影）
    // 特别说明：由于翻转了gASet的顺序，法向量朝向会反过来，但是函数依然能处理此类情况的投影求解。

    // Input data
    Point gS{4, 4, 6};
    Point GA;
    SG::Algebra::PointArray gASet;
    gASet = SG::Algebra::PointArray(6);
    gASet[0] = Point{0.0, 0.0, 0.0};
    gASet[1] = Point{10.5, 0.0 ,1.0};
    gASet[2] = Point{0.5, 10.0 ,0.5};
    gASet[3] = Point{5.24999952316284, 0.0, 0.499999970197678};
    gASet[4] = Point{5.49999952316284, 4.99999952316284 ,0.749999940395355};
    gASet[5] = Point{0.25, 5.0 ,0.25};

    Point GB;
    SG::Algebra::PointArray gBSet;
    gBSet = SG::Algebra::PointArray(8);
    gBSet[3] = Point{2.0, 0.0, 5};
    gBSet[2] = Point{5.5, 0.0, 5.25};
    gBSet[1] = Point{6.0, 5.0, 5.5};
    gBSet[0] = Point{2.5, 6.0, 5.25};
    gBSet[7] = Point{3.75, 0.0, 5.125};
    gBSet[6] = Point{5.75, 2.49999976158142, 5.375};
    gBSet[5] = Point{4.25, 5.0, 5.375};
    gBSet[4] = Point{2.25, 2.49999976158142, 5.125};
    Vector3D nA;
    // Test data
    SG::FEMSolver::Element::CweldCalculator calculator;
    calculator.ComputeProjectionPoint2 (gS,gASet,gBSet,_OUT GA,_OUT GB,_OUT nA);

    // Check
    // ASSERT_NEAR (GA.m_x, 4.50418901443481, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GA.m_y, 4.24252986907959, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GA.m_z, 0.620894312858582, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GB.m_x, 4.11232566833496, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GB.m_y, 4.03538227081299, SG::DataStructure::Common::TOLERANCE);
    // ASSERT_NEAR (GB.m_z, 5.32382535934448, SG::DataStructure::Common::TOLERANCE);
    // 注释掉的为Nastran计算结果，投影点坐标最大误差0.3%。
    ASSERT_NEAR (GA.m_x, 4.505906225, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_y, 4.240975427, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GA.m_z, 0.620987576, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_x, 4.102506725, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_y, 4.044850617, SG::DataStructure::Common::TOLERANCE);
    ASSERT_NEAR (GB.m_z, 5.307687079, SG::DataStructure::Common::TOLERANCE);
}
